﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;

using TLL;
using TLL.Repository;
using TLL.Config;
using TLL.Finance.Currencys;
using TLL.Log;
using TLL.UTL;
using TLL.Debug;
using TLL.Finance;

namespace TLL.Config
{
    public class ConfRepository : XMLRepository<Configuration>
    {
        private string debugURL = string.Empty;
        public ConfRepository(string URL, string debugURL) : base(URL, debugURL, true, true) { this.debugURL = debugURL; }

        public override List<Configuration> Get(int id = 0)
        {
            try
            {
                var res = new List<Configuration>();
                foreach (XmlNode node in Document.ChildNodes[1].ChildNodes)
                {
                    var currencys = new List<Currency>();
                    foreach (XmlNode currency in this.FindNode(node, "currencys").ChildNodes)
                        currencys.Add(new Currency(
                            Utilities.GetEnum<CurrencyType>(currency.Name),
                            Utilities.GetEnum<CurrencyCountry>(currency.Attributes["country"].Value),
                            double.Parse(currency.Attributes["buy"].Value),
                            double.Parse(currency.Attributes["sale"].Value),
                            double.Parse(currency.Attributes["avarageBuyRate"].Value),
                            double.Parse(currency.Attributes["avarageSaleRate"].Value),
                            double.Parse(currency.Attributes["minRate"].Value),
                            double.Parse(currency.Attributes["maxRate"].Value)));

                    res.Add(new Configuration(
                        currencys,
                        this.AttributeByType<int>(node, XMLConfAttrinutes.Count),
                        Utilities.GetEnum<CurrencyType>(this.AttributeByType<string>(node, XMLConfAttrinutes.Currency)),
                        this.AttributeByType<DateTime>(node, XMLConfAttrinutes.Date),
                        this.AttributeByType<DateTime>(node, XMLConfAttrinutes.OUTDate),
                        LogTime.Parse(this.AttributeByType<string>(node, XMLConfAttrinutes.WorkCount))
                    ));
                }
                DebugLogRepository.Add(InformationType.Information, string.Format(@"ConfRepository, Get(id = {0}). Success operation", id), this.debugURL);
                return res;
            }
            catch
            {
                this.Error = new Error(
                    ErrorType.Get, 
                    new Dictionary<string, string>() { 
                        { "ID", id.ToString() }
                });
                DebugLogRepository.Add(InformationType.Error, string.Format(@"ConfRepository, Get(id = {0})
                                       Error title: {1}
                                       Error message: {2}", id, Error.Title, Error.Message), this.debugURL);
                return null;
            }
        }
        public override bool Update(Configuration item, Configuration newitem)
        {
            try
            {
                var node = this.Create_Node(
                    "Item", 
                    Create_Attributes( new Dictionary<Enum,string>() {
                        { XMLConfAttrinutes.Count, newitem.Count.ToString() },
                        { XMLConfAttrinutes.Currency, newitem.CurrencyType.ToString() },
                        { XMLConfAttrinutes.Date, newitem.Date.ToShortDateString() },
                        { XMLConfAttrinutes.OUTDate, newitem.OUTDate.ToShortDateString() },
                        { XMLConfAttrinutes.WorkCount, LogTime.Formated(item.WorkTime) },
                    }));

                var currencysNode = this.Create_Node("currencys", new List<XmlAttribute>());

                foreach (var currency in newitem.Currencys)
                    currencysNode.AppendChild(Create_Node(
                        currency.Type.ToString(),
                        this.Create_Attributes(new Dictionary<string, string>() { 
                            { "buy", currency.Buy.ToString() },
                            { "sale", currency.Sale.ToString() },
                            { "avarageBuyRate", currency.AverageBuyRate.ToString() },
                            { "avarageSaleRate", currency.AverageSaleRate.ToString() },
                            { "country", currency.Country.ToString() },
                            { "minRate", currency.MinRate.ToString() },
                            { "maxRate", currency.MaxRate.ToString() }
                        })
                    ));

                node.AppendChild(currencysNode);
                    
                Document.ChildNodes[1].ReplaceChild(node, Document.ChildNodes[1].FirstChild);

                DebugLogRepository.Add(
                    InformationType.Information, 
                    string.Format(@"ConfRepository, Update(Conf item[name = {0}], Conf newitem[name = {1}]). Success operation", item.ToString(), newitem.ToString()), this.debugURL);

                return true;
            }
            catch 
            {
                this.Error = new Error(
                    ErrorType.Update, 
                    new Dictionary<string, string>() { 
                        { "Name", item.ToString() },
                        { "Name", newitem.ToString() }
                });
                this.Warning = new Warning(
                    WarningType.Update,
                    string.Format("Error updating configuration"),
                    this.Notify, 
                    delegate(object sender, EventArgs e) {
                        this.Error.Show(DisplayDebugType.MessageBox);
                    });
                DebugLogRepository.Add(InformationType.Error, string.Format(@"ConfRepository, Update(Conf item[name = {0}], Conf newitem[name = {1}])
                                       Error title: {2}
                                       Error message: {3}", item.ToString(), newitem.ToString(), Error.Title, Error.Message), this.debugURL);
                return false; 
            }
        }
    }
}
